﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Xml;

namespace fileChecker
{
    class FChecker
    {
        /// <summary>
        /// Каталог клиента/сервера
        /// </summary>
        private string dir;

        /// <summary>
        /// Список файлов в каталоге
        /// </summary>
        private string[] files;

        /// <summary>
        /// Путь к XML файлу
        /// </summary>
        private string PathTo;

        /// <summary>
        /// Служит для выделения относительного пути к файлу
        /// </summary>
        private DirectoryInfo targetDir;

        /// <summary>
        /// Конструктор класса
        /// </summary>
        /// <param name="dir">Каталог клиента/сервера</param>
        /// <param name="name">Имя XML файла</param>
        /// <param name="path">Путь к XML файлу</param>
        public FChecker(string dir, string name, string path)
        {
            this.dir = dir;
            this.PathTo = Path.Combine(path, name + ".xml");
            this.targetDir = new DirectoryInfo(dir);
        }

        /// <summary>
        /// Метод построения XML файла
        /// </summary>
        /// <returns>Возвращается успешность построения</returns>
        public bool buildXML()
        {
            files = Directory.GetFiles(this.dir, "*.*", SearchOption.AllDirectories);

            if (File.Exists(PathTo)) return false; // Проверка на существование файла с таким же именем в каталоге

            using (XmlTextWriter tr = new XmlTextWriter(PathTo, Encoding.UTF8))
            {
                tr.WriteStartDocument();
                tr.WriteStartElement("head");
                tr.WriteEndElement();
            }
            
            XmlDocument doc = new XmlDocument();
            doc.Load(PathTo);

            foreach (string f in files)
            {
                FileInfo fi = new FileInfo(f);
                XmlNode row = doc.CreateElement("File");
                doc.DocumentElement.AppendChild(row);
                XmlAttribute id = doc.CreateAttribute("name");
                id.Value = fi.Name;
                row.Attributes.Append(id);
                XmlAttribute pathRow = doc.CreateAttribute("path");
                pathRow.Value = fi.FullName.Substring(this.targetDir.FullName.IndexOf(this.targetDir.Name) + this.targetDir.Name.Count() + 1);
                row.Attributes.Append(pathRow);
                XmlAttribute hashRow = doc.CreateAttribute("hash");
                hashRow.Value = GetMD5HashFromFile(f);
                row.Attributes.Append(hashRow);
            }
            doc.Save(PathTo);
            return true;
        }

        /// <summary>
        /// Возвращает хеш сумму файла
        /// </summary>
        /// <param name="fileName">Путь к файлу</param>
        /// <returns>Возвращает хеш сумму</returns>
        private string GetMD5HashFromFile(string fileName)
        {
            FileStream file = new FileStream(fileName, FileMode.Open);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] retVal = md5.ComputeHash(file);
            file.Close();
  
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }

            return sb.ToString();
        }


    }
}
